﻿#define _CRT_SECURE_NO_WARNINGS

#include<iostream>
#include<functional>
using namespace std;


namespace wzy
{
	template<class T>
	class auto_ptr
	{
	public:
		auto_ptr(T* ptr)
			:_ptr(ptr)
		{}

		auto_ptr(auto_ptr<T>& ap)
			:_ptr(ap._ptr)
		{
			//转移管理权
			ap._ptr = nullptr;
		}

		auto_ptr<T>& operator=(auto_ptr<T>& ap)
		{
			//判断自己给自己赋值的情况
			if (&ap != this)
			{
				//释放当前资源
				if (_ptr)
					delete _ptr;

				//转移管理器
				_ptr = ap._ptr;
				ap._ptr = nullptr;
			}

			return *this;
		}

		~auto_ptr()
		{
			if (_ptr)
				delete _ptr;
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

	private:
		T* _ptr;
	};

	template<class T>
	class unique_ptr
	{
		//防⽌普通指针隐式类型转换成智能指针对象
		explicit unique_ptr(T* ptr)
			:_ptr(ptr)
		{}

		unique_ptr(const unique_ptr<T>& up) = delete;
		unique_ptr<T>& operator=(const unique_ptr<T>& up) = delete;

		unique_ptr(unique_ptr<T>&& up)
		{
			std::swap(_ptr, up._ptr);
		}

		unique_ptr<T>& operator=(unique_ptr<T>&& up)
		{
			if (this != up._ptr)
			{
				if (_ptr)
					delete _ptr;

				std::swap(_ptr, up._ptr);
			}

			return *this;
		}

		~unique_ptr()
		{
			if (_ptr)
				delete _ptr;
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

	private:
		T* _ptr;
	};


	template<class T>
	class share_ptr
	{
		//防⽌普通指针隐式类型转换成智能指针对象
		explicit share_ptr(T* ptr)
			:_ptr(ptr)
			, _pcount(new int(1))
		{}

		//定制删除器版本
		template<class D>
		share_ptr(T* ptr,D del)
			:_ptr(ptr)
			, _pcount(new int(1))
			,_del(del)	
		{}

		shared_ptr(const share_ptr<T>& sp)
			:_ptr(sp._ptr)
			,_pcount(sp._pcount)
			,_del(sp.del)
		{
			++(*_pcount);
		}

		shared_ptr<T>& operator=(const share_ptr<T>& sp)
		{
			if (this != sp._ptr)
			{
				release();

				_ptr = sp._ptr;
				_pcount = sp._pcount;
				_del = sp._del;
				++(*_pcount);
			}

			return *this;
		}

		~share_ptr()
		{
			release();
		}

		void release()
		{
			if (--(*_pcount) == 0)
			{
				_del(_ptr);
				delete _pcount;
				_ptr = nullptr;
				_pcount = nullptr;
			}
		}

		int ues_count() const
		{
			return *_pcount;
		}

		T& operator*()
		{
			return *_ptr;
		}

		T* operator->()
		{
			return _ptr;
		}

	private:
		T* _ptr;
		int* _pcount;
		//不传入删除器默认调用delete
		function<void(T*)> _del = [](T* ptr) {delete ptr; };
	};
}